﻿using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HPDI.DrawingStandard
{
    public class DimPloter
    {      

        /// <summary>
        /// 线之间角度标注
        /// </summary>
        /// <param name="db"></param>
        /// <param name="L1"></param>
        /// <param name="L2"></param>
        /// <param name="Pref">插入参考点</param>
        /// <param name="scale"></param>
        /// <param name="plotunit"></param>
        /// <param name="paperunit"></param>
        /// <returns></returns>
        public static DBObjectCollection DimAng( Line L1, Line L2, Point3d Pref, double scale=1, Unit plotunit = Unit.Millimeter, Unit paperunit = Unit.Millimeter)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            //ext = new Extents2d(Pref.C2D(), Pref.C2D());
            Dictionary<Unit, double> UnitDic = new Dictionary<Unit, double>()
            {
                { Unit.Meter,1000 },
                { Unit.Centimeter,10 },
                { Unit.Millimeter,1 },
            };
            Dictionary<Unit, string> UnitDicStr = new Dictionary<Unit, string>()
            {
                { Unit.Meter,"M" },
                { Unit.Centimeter,"CM" },
                { Unit.Millimeter,"MM" },
            };
            double factor = UnitDic[plotunit] / UnitDic[paperunit];
            string DimStyleName = string.Format("{0}-{1}-", UnitDicStr[plotunit], UnitDicStr[paperunit]);
            if (scale < 1)
            {
                DimStyleName += Math.Round(1 / scale, 0).ToString() + "-1";
            }
            else
            {
                DimStyleName += "1-" + scale.ToString();
            }
            LineAngularDimension2 AD1;
          

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;
                DimStyleTable dst = (DimStyleTable)tr.GetObject(db.DimStyleTableId, OpenMode.ForRead, true);

                ObjectId dimID = dst[DimStyleName];
                AD1 = new LineAngularDimension2(L1.StartPoint, L1.EndPoint, L2.StartPoint, L2.EndPoint, Pref, "", dimID);
                AD1.Layer = "H标注";

                res.Add(AD1);
                //modelSpace.AppendEntity(AD1);
                //tr.AddNewlyCreatedDBObject(AD1, true);

                //tr.Commit();
                //ext = ext.Add(new Extents2d(AD1.Bounds.Value.MinPoint.C2D(), AD1.Bounds.Value.MaxPoint.C2D()));

            }
            return res;
        }



        /// <summary>
        /// 对齐标注
        /// </summary>
        /// <param name="P1">测量起点</param>
        /// <param name="P2">测量</param>
        /// <param name="Pref">插入参考点</param>
        /// <param name="dimID"></param>
        /// <param name="layerName"></param>
        /// <param name="scale"></param>
        /// <param name="plotunit"></param>
        /// <param name="paperunit"></param>
        /// <returns></returns>
        public static DBObjectCollection DimAli( Point3d P1, Point3d P2, Point3d Pref,double scale = 1, string replaceText = "", Unit plotunit = Unit.Millimeter, Unit paperunit = Unit.Millimeter)
        {
            DBObjectCollection res = new DBObjectCollection();
            Dictionary<Unit, double> UnitDic = new Dictionary<Unit, double>()
            {
                { Unit.Meter,1000 },
                { Unit.Centimeter,10 },
                { Unit.Millimeter,1 },
            };
            Dictionary<Unit, string> UnitDicStr = new Dictionary<Unit, string>()
            {
                { Unit.Meter,"M" },
                { Unit.Centimeter,"CM" },
                { Unit.Millimeter,"MM" },
            };
            double factor = UnitDic[plotunit] / UnitDic[paperunit];
            string DimStyleName = string.Format("{0}-{1}-", UnitDicStr[plotunit], UnitDicStr[paperunit]);
            AlignedDimension AD1;
            //ext = new Extents2d(Pref.C2D(), Pref.C2D());
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;
                DimStyleTable dst = (DimStyleTable)tr.GetObject(db.DimStyleTableId, OpenMode.ForRead);

                if (scale < 1)
                {
                    DimStyleName += Math.Round(1 / scale, 0).ToString() + "-1";
                }
                else
                {
                    DimStyleName += "1-" + scale.ToString();
                }
                var dimID = dst[DimStyleName];
                AD1 = new AlignedDimension(P1, P2, Pref, replaceText, dimID);
                AD1.Layer = "H标注";
                res.Add(AD1);
                //modelSpace.AppendEntity(AD1);
                //tr.AddNewlyCreatedDBObject(AD1, true);
                //tr.Commit();
                //ext = ext.Add(new Extents2d(AD1.Bounds.Value.MinPoint.C2D(), AD1.Bounds.Value.MaxPoint.C2D()));
            }
            return res;
        }

        /// <summary>
        /// 线性标注
        /// </summary>
        /// <param name="db"></param>
        /// <param name="P1">起点</param>
        /// <param name="P2">终点</param>
        /// <param name="Pref">标注位置</param>
        /// <param name="ang">转角，弧度</param>
        /// <param name="scale"></param>
        /// <param name="replaceText"></param>
        /// <param name="pL">合并分段长度（5*100，PL=100）</param>
        /// <param name="tstyle"></param>
        /// <param name="plotunit"></param>
        /// <param name="paperunit"></param>
        /// <returns></returns>
        public static DBObjectCollection DimRot(  Point3d P1, Point3d P2, Point3d Pref
            , double ang = 0, double scale = 1,  string replaceText = "",  Unit plotunit = Unit.Millimeter, Unit paperunit = Unit.Millimeter)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            //ext = new Extents2d(Pref.C2D(), Pref.C2D());
            Dictionary<Unit, double> UnitDic = new Dictionary<Unit, double>()
            {
                { Unit.Meter,1000 },
                { Unit.Centimeter,10 },
                { Unit.Millimeter,1 },
            };
            Dictionary<Unit, string> UnitDicStr = new Dictionary<Unit, string>()
            {
                { Unit.Meter,"M" },
                { Unit.Centimeter,"CM" },
                { Unit.Millimeter,"MM" },
            };
            double factor = UnitDic[plotunit] / UnitDic[paperunit];
            string DimStyleName = string.Format("{0}-{1}-", UnitDicStr[plotunit], UnitDicStr[paperunit]);
            RotatedDimension D1;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;
                DimStyleTable dst = (DimStyleTable)tr.GetObject(db.DimStyleTableId, OpenMode.ForRead);

                if (scale < 1)
                {
                    DimStyleName += Math.Round(1 / scale, 0).ToString() + "-1";
                }
                else
                {
                    DimStyleName += "1-" + scale.ToString();
                }
                string st = DimStyleName;
              
                var dimID = dst[st];

                D1 = new RotatedDimension(GeTools.DegreeToRadian(ang)/*ang*/, P1, P2, Pref, replaceText, dimID);
                D1.Layer = "H标注";
                res.Add(D1);                
            }
            return res;

        }

        /// <summary>
        /// 直径标注测量(结果：D+直径)
        /// </summary>
        /// <param name="db"></param>
        /// <param name="P1"></param>
        /// <param name="P2"></param>
        /// <param name="Pref"></param>
        /// <param name="ang"></param>
        /// <param name="scale"></param>
        /// <param name="dimtxtStyle"></param>
        /// <param name="plotunit"></param>
        /// <param name="paperunit"></param>
        /// <param name="unit"></param>
        /// <returns></returns>
        public static DBObjectCollection DimDiameterRotated( Point3d P1, Point3d P2, Point3d Pref
            , double ang = 0, double scale = 1,Unit plotunit = Unit.Millimeter, Unit paperunit = Unit.Millimeter, string unit = "mm")
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            //ext = new Extents2d(Pref.C2D(), Pref.C2D());
            Dictionary<Unit, double> UnitDic = new Dictionary<Unit, double>()
            {
                { Unit.Meter,1000 },
                { Unit.Centimeter,10 },
                { Unit.Millimeter,1 },
            };
            Dictionary<Unit, string> UnitDicStr = new Dictionary<Unit, string>()
            {
                { Unit.Meter,"M" },
                { Unit.Centimeter,"CM" },
                { Unit.Millimeter,"MM" },
            };
            double factor = UnitDic[plotunit] / UnitDic[paperunit];
            string DimStyleName = string.Format("{0}-{1}-", UnitDicStr[plotunit], UnitDicStr[paperunit]);
            if (scale < 1)
            {
                DimStyleName += Math.Round(1 / scale, 0).ToString() + "-1";
            }
            else
            {
                DimStyleName += "1-" + scale.ToString();
            }
            RotatedDimension D1;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;
                DimStyleTable dst = (DimStyleTable)tr.GetObject(db.DimStyleTableId, OpenMode.ForRead);

                var dimID = dst[DimStyleName];

                D1 = new RotatedDimension(GeTools.DegreeToRadian(0)/*ang*/, P1, P2, Pref, "", dimID);
                D1.Layer = "H标注";
               
                D1.DimensionText = "D" + D1.Measurement.ToString();
                

                res.Add(D1);
                //modelSpace.AppendEntity(D1);
                //tr.AddNewlyCreatedDBObject(D1, true);
               
                  
                //tr.Commit();
                //ext = ext.Add(new Extents2d(D1.Bounds.Value.MinPoint.C2D(), D1.Bounds.Value.MaxPoint.C2D()));

            }
            return res;

        }

        private static DBObjectCollection AddListDimRotated( 
            Point3d Pref, List<Point3d> npts,  int scale, double ang = 0, int pN = 1, Unit plotunit = Unit.Millimeter, Unit paperunit = Unit.Millimeter)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            //ext = new Extents2d(Pref.C2D(), Pref.C2D());
            Dictionary<Unit, double> UnitDic = new Dictionary<Unit, double>()
            {
                { Unit.Meter,1000 },
                { Unit.Centimeter,10 },
                { Unit.Millimeter,1 },
            };
            Dictionary<Unit, string> UnitDicStr = new Dictionary<Unit, string>()
            {
                { Unit.Meter,"M" },
                { Unit.Centimeter,"CM" },
                { Unit.Millimeter,"MM" },
            };
            double factor = UnitDic[plotunit] / UnitDic[paperunit];
            string DimStyleName = string.Format("{0}-{1}-", UnitDicStr[plotunit], UnitDicStr[paperunit]);

            RotatedDimension D1 = new RotatedDimension();

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;

                DimStyleTable dst = (DimStyleTable)tr.GetObject(db.DimStyleTableId, OpenMode.ForRead);
                var dimID = dst[string.Format("1-{0:G}", scale)];

                if (npts.Count > 1)
                {
                    if (pN == 1)
                    {
                        for (int i = 0; i < npts.Count - 1; i++)
                        {
                            Point3d P1 = npts[i];
                            Point3d P2 = npts[i + 1];
                            //Point3d Pref = GeTools.MidPoint(P1, P2).C3D(3, 3);
                            D1 = new RotatedDimension(GeTools.DegreeToRadian(ang), P1, P2, Pref, "", dimID);
                            D1.Layer = "H标注";
                          
                            res.Add(D1);
                            //modelSpace.AppendEntity(D1);
                            //tr.AddNewlyCreatedDBObject(D1, true);
                        }
                    }
                    else
                    {
                        if (npts.Count == 2)
                        {
                            Point3d P1 = npts[0];
                            Point3d P2 = npts[1];
                            //Point3d Pref = GeTools.MidPoint(P1, P2).C3D(0, 3);
                            D1 = new RotatedDimension(GeTools.DegreeToRadian(ang), P1, P2, Pref, "", dimID);
                            D1.Layer = "H标注";
                            string replaceText = (D1.Measurement / pN) + "×" + pN;
                            D1.DimensionText = replaceText;
                          
                            res.Add(D1);
                            //modelSpace.AppendEntity(D1);
                            //tr.AddNewlyCreatedDBObject(D1, true);
                        }
                    }
                }
                //tr.Commit();
                //ext = ext.Add(new Extents2d(D1.Bounds.Value.MinPoint.C2D(), D1.Bounds.Value.MaxPoint.C2D()));

            }
            return res;
        }


        /// <summary>
        /// 绘制标高符号
        /// </summary>
        /// <param name="bgdata">标高数据</param>
        /// <param name="refpt">标高点</param>
        /// <param name="s">放大倍数</param>
        public static ObjectId AddBG( double bgdata, Point3d refpt,  double scale = 1)
        {
            Database db = HostApplicationServices.WorkingDatabase;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                ObjectId blkRecId = blockTbl["KYBG"];
                //BlockReference acBlkRef = new BlockReference(refpt, blkRecId);
                ObjectId id;
                using (BlockReference acBlkRef = new BlockReference(refpt, blkRecId))
                {
                    double factor = scale / 100;
                    //acBlkRef.SetAttributes();
                    acBlkRef.ScaleFactors = new Scale3d(factor);
                    acBlkRef.Layer = "H标注";
                    id = recorder.AppendEntity(acBlkRef);
                    tr.AddNewlyCreatedDBObject(acBlkRef, true);

                    BlockTableRecord zheshiyuankuai;
                    zheshiyuankuai = tr.GetObject(blkRecId, OpenMode.ForRead) as BlockTableRecord;
                    foreach (ObjectId gezhongshuxingID in zheshiyuankuai)
                    {
                        DBObject gezhongshuxing = tr.GetObject(gezhongshuxingID, OpenMode.ForRead) as DBObject;
                        if (gezhongshuxing is AttributeDefinition)
                        {
                            AttributeDefinition acAtt = gezhongshuxing as AttributeDefinition;
                            using (AttributeReference acAttRef = new AttributeReference())
                            {
                                string stext = string.Format("{0:f3}", bgdata);
                                acAttRef.SetAttributeFromBlock(acAtt, acBlkRef.BlockTransform);
                                acAttRef.Position = acAtt.Position.TransformBy(acBlkRef.BlockTransform);
                                acAttRef.TextString = stext;
                                //acAttRef.Height = acAttRef.Height * factor;
                                acBlkRef.AttributeCollection.AppendAttribute(acAttRef);

                                tr.AddNewlyCreatedDBObject(acAttRef, true);
                                //ext = ext.Add(new Extents2d(acBlkRef.Bounds.Value.MinPoint.C2D(), acBlkRef.Bounds.Value.MaxPoint.C2D()));
                            }
                        }
                    }
                }
                tr.Commit();
                return id;
            }
          
        }


        /// <summary>
        /// 绘制上下标记符号
        /// </summary>
        /// <param name="bJdata">标记信息</param>
        /// <param name="refpt">标记点</param>
        /// <param name="s"></param>
        public static ObjectId AddPMBJ( string bJdata, Point3d refpt,  double scale = 1, double textHeight = 3, bool isTop = true)
        {
           
            Database db = HostApplicationServices.WorkingDatabase;
  
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;


                ObjectId blkRecId = blockTbl["TP"];
                if (!isTop)
                    blkRecId = blockTbl["BP"];
                double factor = scale / 100;
                ObjectId id;
                using (BlockReference acBlkRef = new BlockReference(refpt, blkRecId))
                {
                    //acBlkRef.SetAttributes();
                    acBlkRef.ScaleFactors = new Scale3d(factor);
                    acBlkRef.Layer = "H标注";
                    id= recorder.AppendEntity(acBlkRef);
                    tr.AddNewlyCreatedDBObject(acBlkRef, true);
                    BlockTableRecord zheshiyuankuai;
                    zheshiyuankuai = tr.GetObject(blkRecId, OpenMode.ForRead) as BlockTableRecord;
                    foreach (ObjectId gezhongshuxingID in zheshiyuankuai)
                    {
                        DBObject gezhongshuxing = tr.GetObject(gezhongshuxingID, OpenMode.ForRead) as DBObject;
                        if (gezhongshuxing is AttributeDefinition)
                        {
                            AttributeDefinition acAtt = gezhongshuxing as AttributeDefinition;
                            using (AttributeReference acAttRef = new AttributeReference())
                            {
                                acAttRef.SetAttributeFromBlock(acAtt, acBlkRef.BlockTransform);
                                acAttRef.Position = acAtt.Position.TransformBy(acBlkRef.BlockTransform);
                                acAttRef.TextString = bJdata;
                                //acAttRef.Height = 2;
                                //acAttRef.Height = textHeight * factor;
                                acBlkRef.AttributeCollection.AppendAttribute(acAttRef);

                                tr.AddNewlyCreatedDBObject(acAttRef, true);
                                //ext = ext.Add(new Extents2d(acBlkRef.Bounds.Value.MinPoint.C2D(), acBlkRef.Bounds.Value.MaxPoint.C2D()));
                            }
                        }
                    }
                }
                tr.Commit();
                 return id;

            }

        }

        /// <summary>
        ///   绘制左右标记符号
        /// </summary>
        /// <param name="bJdata">标记信息</param>
        /// <param name="refpt">标记点</param>

        /// <param name="s"></param>
        /// <param name="textHeight"></param>
        /// <param name="isLeft"></param>
        public static ObjectId AddZYBJ(string bJdata, Point3d refpt, double scale = 1, double textHeight = 3, bool isLeft = true)
        {
            
            Database db = HostApplicationServices.WorkingDatabase;
            double factor = scale / 100;//默认初始放大100倍
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;
                ObjectId blkRecId = blockTbl["ZB"];
                if (!isLeft)
                    blkRecId = blockTbl["YB"];
                ObjectId id;
                using (BlockReference acBlkRef = new BlockReference(refpt, blkRecId))
                {
                    //acBlkRef.SetAttributes();
                    acBlkRef.ScaleFactors = new Scale3d(factor);
                    acBlkRef.Layer = "H标注";
                    id= modelSpace.AppendEntity(acBlkRef);
                    tr.AddNewlyCreatedDBObject(acBlkRef, true);
                   

                    BlockTableRecord zheshiyuankuai;
                    zheshiyuankuai = tr.GetObject(blkRecId, OpenMode.ForRead) as BlockTableRecord;
                    foreach (ObjectId gezhongshuxingID in zheshiyuankuai)
                    {
                        DBObject gezhongshuxing = tr.GetObject(gezhongshuxingID, OpenMode.ForRead) as DBObject;
                        if (gezhongshuxing is AttributeDefinition)
                        {
                            AttributeDefinition acAtt = gezhongshuxing as AttributeDefinition;
                            using (AttributeReference acAttRef = new AttributeReference())
                            {
                                acAttRef.SetAttributeFromBlock(acAtt, acBlkRef.BlockTransform);
                                acAttRef.Position = acAtt.Position.TransformBy(acBlkRef.BlockTransform);
                                acAttRef.TextString = bJdata;
                                //acAttRef.Height = 2;
                                //acAttRef.Height = textHeight * factor;
                                acBlkRef.AttributeCollection.AppendAttribute(acAttRef);

                                tr.AddNewlyCreatedDBObject(acAttRef, true);
                            }
                        }
                    }
                }
                tr.Commit();
                return id;
            }
            
        }


        /// <summary>
        /// （水平或垂直）剖断线
        /// </summary>
        /// <param name="stPoint">起点</param>
        /// <param name="endPoint">终点</param>
        /// <param name="scale">比例尺</param>
        /// <param name="layer">图层</param>
        /// <param name="isDrawing">是否绘制</param>
        public static DBObjectCollection AddBreakLine(Point2d stPoint, Point2d endPoint, double scale = 1, string layer = "H标注")
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            Polyline line = new Polyline() { Closed = false, Layer = layer, Plinegen = true };//定义不封闭的Polyline 平面虚线
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder;
                recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                #region
                Point2d centerPt = GeTools.MidPoint(stPoint.C3D(), endPoint.C3D()).C2D();
                //画线

                if (stPoint.Y > endPoint.Y && stPoint.X == endPoint.X)
                {
                    line.AddVertexAt(0, stPoint, 0, 0, 0);
                    line.AddVertexAt(1, centerPt.C2D(0, 1.7941 * scale), 0, 0, 0);
                    line.AddVertexAt(2, centerPt.C2D(-2.4148 * scale, 1.147 * scale), 0, 0, 0);
                    line.AddVertexAt(3, centerPt, 0, 0, 0);
                    line.AddVertexAt(4, centerPt.C2D(2.4148 * scale, -1.147 * scale), 0, 0, 0);
                    line.AddVertexAt(5, centerPt.C2D(0, -1.7941 * scale), 0, 0, 0);
                    line.AddVertexAt(6, endPoint, 0, 0, 0);
                }
                else if (stPoint.Y <= endPoint.Y && stPoint.X == endPoint.X)
                {
                    line.AddVertexAt(0, endPoint, 0, 0, 0);
                    line.AddVertexAt(1, centerPt.C2D(0, 1.7941 * scale), 0, 0, 0);
                    line.AddVertexAt(2, centerPt.C2D(-2.4148 * scale, 1.147 * scale), 0, 0, 0);
                    line.AddVertexAt(3, centerPt, 0, 0, 0);
                    line.AddVertexAt(4, centerPt.C2D(2.4148 * scale, -1.147 * scale), 0, 0, 0);
                    line.AddVertexAt(5, centerPt.C2D(0, -1.7941 * scale), 0, 0, 0);
                    line.AddVertexAt(6, stPoint, 0, 0, 0);
                }

                if (stPoint.X > endPoint.X && stPoint.Y == endPoint.Y)
                {
                    line.AddVertexAt(0, stPoint, 0, 0, 0);
                    line.AddVertexAt(1, centerPt.C2D(1.7941 * scale, 0), 0, 0, 0);
                    line.AddVertexAt(2, centerPt.C2D(1.147 * scale, -2.4148 * scale), 0, 0, 0);
                    line.AddVertexAt(3, centerPt, 0, 0, 0);
                    line.AddVertexAt(4, centerPt.C2D(-1.147 * scale, 2.4148 * scale), 0, 0, 0);
                    line.AddVertexAt(5, centerPt.C2D(-1.7941 * scale, 0), 0, 0, 0);
                    line.AddVertexAt(6, endPoint, 0, 0, 0);
                }
                else if (stPoint.X <= endPoint.X && stPoint.Y == endPoint.Y)
                {
                    line.AddVertexAt(0, endPoint, 0, 0, 0);
                    line.AddVertexAt(1, centerPt.C2D(1.7941 * scale, 0), 0, 0, 0);
                    line.AddVertexAt(2, centerPt.C2D(1.147 * scale, -2.4148 * scale), 0, 0, 0);
                    line.AddVertexAt(3, centerPt, 0, 0, 0);
                    line.AddVertexAt(4, centerPt.C2D(-1.147 * scale, 2.4148 * scale), 0, 0, 0);
                    line.AddVertexAt(5, centerPt.C2D(-1.7941 * scale, 0), 0, 0, 0);
                    line.AddVertexAt(6, stPoint, 0, 0, 0);
                }
                res.Add(line);

                #endregion
            }
            return res;
        }

        /// <summary>
        /// 绘制水平剖断线
        /// </summary>
        /// <param name="stPoint"></param>
        /// <param name="endPoint"></param>
        /// <param name="scale">线性比例</param>
        /// <param name="layer">图层</param>
        /// <returns></returns>
        private static DBObjectCollection AddUpperAndDownBreakLine(Database db, Point2d stPoint, Point2d endPoint, double scale = 20, string layer = "H标注")
        {
            DBObjectCollection res = new DBObjectCollection();
            Polyline line = new Polyline() { Closed = false, Layer = layer, Plinegen = true };//定义不封闭的Polyline 平面虚线
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder;
                recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                #region
                Point2d centerPt = GeTools.MidPoint(stPoint.C3D(), endPoint.C3D()).C2D();
                //画线
                if (stPoint.X > endPoint.X)
                {
                    line.AddVertexAt(0, stPoint, 0, 0, 0);
                    line.AddVertexAt(1, centerPt.C2D(1.7941 * scale, 0), 0, 0, 0);
                    line.AddVertexAt(2, centerPt.C2D(1.147 * scale, -2.4148 * scale), 0, 0, 0);
                    line.AddVertexAt(3, centerPt, 0, 0, 0);
                    line.AddVertexAt(4, centerPt.C2D(-1.147 * scale, 2.4148 * scale), 0, 0, 0);
                    line.AddVertexAt(5, centerPt.C2D(-1.7941 * scale, 0), 0, 0, 0);
                    line.AddVertexAt(6, endPoint, 0, 0, 0);
                }
                else
                {
                    line.AddVertexAt(0, endPoint, 0, 0, 0);
                    line.AddVertexAt(1, centerPt.C2D(1.7941 * scale, 0), 0, 0, 0);
                    line.AddVertexAt(2, centerPt.C2D(1.147 * scale, -2.4148 * scale), 0, 0, 0);
                    line.AddVertexAt(3, centerPt, 0, 0, 0);
                    line.AddVertexAt(4, centerPt.C2D(-1.147 * scale, 2.4148 * scale), 0, 0, 0);
                    line.AddVertexAt(5, centerPt.C2D(-1.7941 * scale, 0), 0, 0, 0);
                    line.AddVertexAt(6, stPoint, 0, 0, 0);
                }
                res.Add(line);

                #endregion
            }
            return res;
        }


        /// <summary>
        /// 增加引线
        /// </summary>
        /// <param name="anchor">标注点</param>
        /// <param name="textAnchor">文字左上角点</param>
        /// <param name="cont">文字内容</param>
        /// <param name="scale">比例</param>
        /// <returns></returns>
        public static DBObjectCollection AddMLeader(Point2d anchor, Point2d textAnchor, string cont,double scale)
        {
            Database db = HostApplicationServices.WorkingDatabase;
            DBObjectCollection ret = new DBObjectCollection();
            MLeader mleader = new MLeader();

            string DimStyleName = "ML";
            if (scale < 1)
            {
                DimStyleName += Math.Round(1 / scale, 0).ToString() + "-1";
            }
            else
            {
                DimStyleName += "1-" + scale.ToString();
            }

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary mlstyles = (DBDictionary)tr.GetObject(db.MLeaderStyleDictionaryId, OpenMode.ForRead);
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                mleader.MLeaderStyle = (ObjectId)mlstyles[DimStyleName];

                mleader.MText = new MText()
                {
                    Contents = cont,
                    Location = textAnchor.C3D(),

                    TextStyleId = st["H仿宋"],
                    Height = 2.5 ,
                    Layer = "H标注",
                    LineSpacingStyle = LineSpacingStyle.Exactly,
                };
                mleader.MText.LineSpaceDistance = 3.5*scale;
                mleader.MText.Attachment = AttachmentPoint.BottomLeft;
                int idx = mleader.AddLeaderLine(anchor.C3D());
            }
            mleader.Layer = "H标注";
            ret.Add(mleader);
            return ret;
        }

        //public static MLeader CreatMLeader(Database db, Point2d anchor, string cont, bool isLeft)
        //{
        //    double scale = 0.25;
        //    MLeader ret = new MLeader();

        //    Point2d textAnchor;
        //    double w = (from a in Regex.Split(cont, "\n") select a.Length).Max() * 2.5 * 0.7 * scale * TextHelper.Factor;
        //    if (isLeft)
        //    {
        //        textAnchor = anchor.Convert2D(-w - 2, 2);
        //    }
        //    else
        //    {
        //        textAnchor = anchor.Convert2D(2, 2);
        //    }


        //    using (Transaction tr = db.TransactionManager.StartTransaction())
        //    {
        //        DBDictionary mlstyles = (DBDictionary)tr.GetObject(db.MLeaderStyleDictionaryId, OpenMode.ForRead);
        //        TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
        //        ret.MLeaderStyle = (ObjectId)mlstyles["ML"];
        //        ret.MText = new MText()
        //        {
        //            Contents = cont,
        //            Location = textAnchor.Convert3D(),
        //            TextStyleId = st["仿宋"],
        //            Height = 2.5 * scale,
        //            Layer = "标注",
        //            LineSpacingStyle = LineSpacingStyle.Exactly,
        //        };
        //        ret.TextHeight = 2.5 * scale;
        //        ret.MText.LineSpaceDistance = 0.875;
        //        ret.MText.LineSpacingFactor = 0.875;
        //        int idx = ret.AddLeaderLine(anchor.Convert3D());
        //    }
        //    ret.Layer = "标注";
        //    return ret;
        //}

        /// <summary>
        /// 弧形标注（左边为单弧）
        /// </summary>
        /// <param name="insertPt">插入点（左右两边的中心点）</param>
        /// <param name="lineWidth">左右弧的总宽度</param>
        /// <param name="arcAngle">弧形角度</param>
        /// <param name="degree">旋转角度</param>
        /// <returns></returns>
        public static DBObjectCollection ArcUpBreakLine(Point2d insertPt, double lineWidth, double arcAngle = 45, double degree = 0)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // 计算圆弧半径
                double arcRadius = Math.Abs(lineWidth / 4 / Math.Sin(GeTools.DegreeToRadian(arcAngle / 2)));
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                Arc arc1 = new Arc(insertPt.C3D(-arcRadius * Math.Sin(GeTools.DegreeToRadian(arcAngle / 2)), arcRadius * Math.Cos(GeTools.DegreeToRadian(arcAngle / 2))),
                    arcRadius, GeTools.DegreeToRadian(270- arcAngle/2), GeTools.DegreeToRadian(270 + arcAngle/2))
                { Layer = "H标注" };

                Arc arc2 = new Arc(insertPt.C3D((arcRadius * Math.Sin(GeTools.DegreeToRadian(arcAngle / 2))), -(arcRadius * Math.Cos(GeTools.DegreeToRadian(arcAngle / 2)))),
                    arcRadius, GeTools.DegreeToRadian(90- arcAngle / 2), GeTools.DegreeToRadian(90 + arcAngle / 2))
                { Layer = "H标注" };

                Arc arc3 = new Arc(insertPt.C3D((arcRadius * Math.Sin(GeTools.DegreeToRadian(arcAngle / 2))), arcRadius * Math.Cos(GeTools.DegreeToRadian(arcAngle / 2))),
                    arcRadius, GeTools.DegreeToRadian(270 - arcAngle / 2), GeTools.DegreeToRadian(270 + arcAngle / 2))
                { Layer = "H标注" };

                res.Add(arc1);
                res.Add(arc2);
                res.Add(arc3);

                var TX1 = Matrix3d.Rotation(GeTools.DegreeToRadian(degree), Vector3d.ZAxis, insertPt.C3D());
                foreach (DBObject item in res)
                {
                    Entity pr = (Entity)item;
                    pr.TransformBy(TX1);
                }
                return res;
            }
        }

        /// <summary>
        /// 弧形标注（左边为双弧）
        /// </summary>
        /// <param name="insertPt">插入点（左右两边的中心点）</param>
        /// <param name="lineWidth">左右弧的总宽度</param>
        /// <param name="arcAngle">弧形角度</param>
        /// <param name="degree">旋转角度</param>
        /// <returns></returns>
        public static DBObjectCollection ArcBottomBreakLine(Point2d insertPt, double lineWidth, double arcAngle = 45, double degree = 0)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // 计算圆弧半径
                double arcRadius = Math.Abs(lineWidth / 4 / Math.Sin(GeTools.DegreeToRadian(arcAngle / 2)));
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;


                Arc arc1 = new Arc(insertPt.C3D(-arcRadius * Math.Sin(GeTools.DegreeToRadian(arcAngle / 2)), -arcRadius * Math.Cos(GeTools.DegreeToRadian(arcAngle / 2))),
                    arcRadius, GeTools.DegreeToRadian(90 - arcAngle / 2), GeTools.DegreeToRadian(90 + arcAngle / 2))
                { Layer = "H标注" };

                Arc arc2 = new Arc(insertPt.C3D((arcRadius * Math.Sin(GeTools.DegreeToRadian(arcAngle / 2))), arcRadius * Math.Cos(GeTools.DegreeToRadian(arcAngle / 2))),
                    arcRadius, GeTools.DegreeToRadian(270 - arcAngle / 2), GeTools.DegreeToRadian(270 + arcAngle / 2))
                { Layer = "H标注" };

                Arc arc3 = new Arc(insertPt.C3D((-arcRadius * Math.Sin(GeTools.DegreeToRadian(arcAngle / 2))), arcRadius * Math.Cos(GeTools.DegreeToRadian(arcAngle / 2))),
                    arcRadius, GeTools.DegreeToRadian(270 - arcAngle / 2), GeTools.DegreeToRadian(270 + arcAngle / 2))
                { Layer = "H标注" };

                res.Add(arc1);
                res.Add(arc2);
                res.Add(arc3);

                var TX1 = Matrix3d.Rotation(GeTools.DegreeToRadian(degree), Vector3d.ZAxis, insertPt.C3D());
                foreach (DBObject item in res)
                {
                    Entity pr = (Entity)item;
                    pr.TransformBy(TX1);
                }
                return res;
            }
        }

        /// <summary>
        /// 增加方向指向标识()
        /// </summary>
        /// <param name="OrigenPoint">插入点</param>
        /// <param name="text">方向指向地名称</param>
        /// <param name="height">文本高度</param>
        /// <param name="scale">比例尺</param>
        /// <param name="isLeft">朝左朝右</param>
        /// <param name="TextStyle">文本样式</param>
        /// <param name="layer">图层</param>
        /// <returns></returns>
        public static DBObjectCollection AddArrowTitle(Point3d OrigenPoint, string text, double height = 2.5, double scale = 1, bool isLeft = false, string TextStyle = "H仿宋", string layer = "H标注")
        {
            Database db = HostApplicationServices.WorkingDatabase;
            DBObjectCollection res = new DBObjectCollection();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {

                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;

                MText num = new MText();
                num.Contents = text;
                num.TextHeight = height*scale;
                double w = num.ActualWidth;// height * 1.25 * text.Length / (0.5 * 2.5*scal);

                if (isLeft)
                {
                    OrigenPoint = OrigenPoint.C3D(-w - 5 * scale);
                    num.Location = OrigenPoint.C3D(3 * scale, 5 * scale);
                }
                else
                {
                    OrigenPoint = OrigenPoint.C3D(w + 5 * scale);
                    num.Location = OrigenPoint.C3D(-3 * scale - w * 0.75, 5 * scale);
                }



                num.TextStyleId = st[TextStyle];
                num.Layer = layer;
                res.Add(num);
                //modelSpace.AppendEntity(num);
                //tr.AddNewlyCreatedDBObject(num, true);

                Polyline Paa0 = new Polyline() { Closed = true };
                if (isLeft)
                {
                    Paa0.AddVertexAt(0, OrigenPoint.C2D(0, 0), 0, 0, 0);

                    Paa0.AddVertexAt(1, OrigenPoint.C2D(2 * scale, 1.5 * scale), 0, 0, 0);
                    Paa0.AddVertexAt(2, OrigenPoint.C2D(2 * scale, 0.5 * scale), 0, 0, 0);

                    Paa0.AddVertexAt(3, OrigenPoint.C2D(3 * scale + w, 0.5 * scale), 0, 0, 0);
                    Paa0.AddVertexAt(4, OrigenPoint.C2D(3 * scale + w, -0.5 * scale), 0, 0, 0);
                    Paa0.AddVertexAt(5, OrigenPoint.C2D(2 * scale, -0.5 * scale), 0, 0, 0);
                    Paa0.AddVertexAt(6, OrigenPoint.C2D(2 * scale, -1.5 * scale), 0, 0, 0);
                }
                else
                {
                    Paa0.AddVertexAt(0, OrigenPoint.C2D(0, 0), 0, 0, 0);

                    Paa0.AddVertexAt(1, OrigenPoint.C2D(-2 * scale, 1.5 * scale), 0, 0, 0);
                    Paa0.AddVertexAt(2, OrigenPoint.C2D(-2 * scale, 0.5 * scale), 0, 0, 0);

                    Paa0.AddVertexAt(3, OrigenPoint.C2D(-3 * scale - w, 0.5 * scale), 0, 0, 0);
                    Paa0.AddVertexAt(4, OrigenPoint.C2D(-3 * scale - w, -0.5 * scale), 0, 0, 0);
                    Paa0.AddVertexAt(5, OrigenPoint.C2D(-2 * scale, -0.5 * scale), 0, 0, 0);
                    Paa0.AddVertexAt(6, OrigenPoint.C2D(-2 * scale, -1.5 * scale), 0, 0, 0);
                }


                Paa0.Layer = layer;
                res.Add(Paa0);

            }
            return res;
        }

        /// <summary>
        /// 添加带线的圆文本
        /// </summary>
        /// <param name="textstring">圆文本</param>
        /// <param name="PositionPoint">起点</param>
        /// <param name="endP">终点</param>
        /// <param name="isTop">圆在线上部或者线下部</param>
        /// <param name="TextStyle"></param>
        /// <param name="scale"></param>
        /// <param name="txtHeight"></param>
        /// <param name="cR"></param>
        /// <returns></returns>
        public static DBObjectCollection AddLineCirText(string textstring, Point2d PositionPoint, Point2d endP, bool isTop = true, string TextStyle = "H仿宋", double scale = 1, double txtHeight = 2.5, double cR = 3)
        {
            Database db = HostApplicationServices.WorkingDatabase;
            DBObjectCollection res = new DBObjectCollection();
            DBText txt = new DBText();
            Circle C1 = new Circle();
            Line L1, L2;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;

                txt.TextString = textstring.ToString();
                txt.Height = txtHeight * scale;
                txt.Position = PositionPoint.C3D();
                txt.HorizontalMode = TextHorizontalMode.TextCenter;
                txt.VerticalMode = TextVerticalMode.TextVerticalMid;
                txt.AlignmentPoint = PositionPoint.C3D();
                txt.TextStyleId = st[TextStyle];
                txt.Layer = "H标注";
                txt.WidthFactor = st[TextStyle].GetXScale();

                C1 = new Circle(PositionPoint.C3D(), Vector3d.ZAxis, cR * scale);
                C1.Layer = "H细线";

                if(isTop)
                   L1 = new Line(PositionPoint.C3D(0, -3 * scale), endP.C3D());
                else
                   L1 = new Line(PositionPoint.C3D(0, 3 * scale), endP.C3D());
                L1.Layer = "H虚线";

                res.Add(txt);
                res.Add(C1);
                res.Add(L1);
            }
            return res;
        }

        /// <summary>
        /// 添加外包圆文本
        /// </summary>
        /// <param name="textstring">文本内容</param>
        /// <param name="PositionPoint">插入点</param>
        /// <param name="scale">比例尺</param>
        /// <param name="TextStyle">样式</param>
        /// <param name="ang">角度</param>
        /// <param name="txtHeight"></param>
        /// <param name="cR"></param>
        /// <returns></returns>
        public static DBObjectCollection AddCirText(string textstring, Point2d PositionPoint, double scale = 1,string TextStyle = "H仿宋", double ang = 0, double txtHeight = 2.5, double cR = 2.7)
        {
            Database db = HostApplicationServices.WorkingDatabase;
            DBObjectCollection res = new DBObjectCollection();
            DBText txt = new DBText();         
            Circle C2 = new Circle();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;


                txt.TextString = textstring.ToString();
                txt.Height = txtHeight * scale;
                txt.Position = PositionPoint.C3D();
                txt.HorizontalMode = TextHorizontalMode.TextCenter;
                txt.VerticalMode = TextVerticalMode.TextVerticalMid;
                txt.AlignmentPoint = PositionPoint.C3D();
                txt.Rotation =GeTools.DegreeToRadian(ang);
                txt.TextStyleId = st[TextStyle];
                txt.Layer = "H标注";
                txt.WidthFactor = st[TextStyle].GetXScale();


                C2 = new Circle(PositionPoint.C3D(), Vector3d.ZAxis, cR * scale);
                C2.Layer = "H标注";

                res.Add(txt);
                res.Add(C2);
            }
            return res;
        }
    }
}


